home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 32
/
Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso
/
Aminet
/
dev
/
lang
/
Python152_Src.lha
/
Python152_Source
/
Amiga
/
unixemul.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-04-27
|
7KB
|
356 lines
/**************************************************************\
** **
** UNIX 'emulation' functions for AmigaDOS **
** **
** Made by Irmen de Jong (irmen@bigfoot.com) **
** **
** 21-jan-98: Created. Moved some functions from **
** Modules/Amigamodule.c to here. **
** 25-dec-98: Added I-Net 225 support **
** Added ftruncate (but not used due to bugs) **
** **
** NOTE: Don't forget __io2errno conversion!!!!!!!!!!!!!!!! **
** **
\**************************************************************/
#ifndef INET225
#include <dos.h>
#endif
#include <sys/stat.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <dos/dostags.h>
#include <exec/execbase.h>
#ifdef AMITCP
#include <proto/usergroup.h>
#include <proto/socket.h>
#endif
#ifdef INET225
#include <proto/socket.h>
static int _OSERR;
#endif
#include "Python.h"
#include "protos.h"
/************ Utility functions *************/
/*** checkLink: check for link loops and other errors ***/
static BOOL checkLink(char *from, BPTR to, BOOL root)
{
struct FileInfoBlock __aligned fib;
if(Examine(to,&fib))
{
if(fib.fib_EntryType>0)
{
// directory! Check some things (loops etc)
char* pp;
char p;
BPTR fromLock,temp;
// only superuser may link directories
if(!root)
{
errno=EPERM; return FALSE;
}
pp = PathPart(from);
p = *pp;
*pp = 0;
fromLock=Lock(from,SHARED_LOCK);
*pp=p;
if(fromLock)
{
do {
if(SameLock(fromLock,to)==LOCK_SAME)
{
UnLock(fromLock);
errno = ELOOP;
return FALSE; // link loop
}
temp = fromLock;
fromLock = ParentDir(fromLock);
UnLock(temp);
} while (fromLock);
return TRUE; // dir, OK.
}
else errno=__io2errno(_OSERR=IoErr());
}
else return TRUE; // file, OK.
}
else errno=__io2errno(_OSERR=IoErr());
return FALSE;
}
/************ link(2) : make a hard link ************/
/* LINK: make hardlink from 'from' to 'to' (to must exist, from is new) */
/* 'from' may not be a directory if you are not the super-user. */
/* 0=ok, -1=err */
int link(const char *to, const char *from)
{
BOOL root;
BPTR toLock;
/* are we superuser? */
#ifdef AMITCP
if (!checkusergrouplib())
#else
if (!checksocketlib())
#endif
{
PyErr_Clear();
root=TRUE; /* can't tell... so be root */
}
else if(getuid()==0) root = TRUE;
else root=FALSE;
if(toLock=Lock(to,SHARED_LOCK))
{
if(checkLink(from,toLock,root))
{
if(MakeLink(from,(LONG)toLock,FALSE))
{
UnLock(toLock);
return 0;
}
else errno=__io2errno(_OSERR=IoErr());
}
UnLock(toLock);
}
else errno=__io2errno(_OSERR=IoErr());
return -1;
}
/************** symlink(2): create symbolic (soft) link ********/
int symlink(const char *to, const char *from)
{
/* symbolic link 'from' is created to 'to' */
/* 0=ok, else -1 + errno */
BPTR toLock;
if(toLock=Lock(to,SHARED_LOCK))
{
if(checkLink(from,toLock,TRUE))
{
UnLock(toLock);
if(MakeLink(from,(LONG)to,TRUE)) return 0;
else errno=__io2errno(_OSERR=IoErr());
}
else UnLock(toLock);
}
else errno=__io2errno(_OSERR=IoErr());
return -1;
}
/************** readlink(2): read value of a symbolic link ***********/
int readlink(const char *path, char *buf, int bufsiz)
{
struct MsgPort *port;
struct stat st;
if(!(port=DeviceProc(path)))
{
errno=EIO; return -1;
}
buf[bufsiz-1]=0;
errno=0;
if(lstat(path,&st)>=0)
{
if(S_ISLNK(st.st_mode))
{
char c;
BPTR dirlock;
BPTR olddir;
char *p;
char *link;
p = PathPart(path);
link = FilePart(path);
c = *p; *p='\0';
dirlock=Lock(path,ACCESS_READ); *p=c;
if(dirlock)
{
olddir=CurrentDir(dirlock);
if(!ReadLink(port,dirlock,link,buf,bufsiz))
errno=__io2errno(_OSERR=IoErr());
dirlock=CurrentDir(olddir);
UnLock(dirlock);
}
else errno=__io2errno(_OSERR=IoErr());
}
else errno=EINVAL;
}
if(errno!=0) return -1;
if(buf[bufsiz-1]==0) return strlen(buf);
else return bufsiz;
}
/** custom mkdir() implementation **/
/** This version actually sets protection bits **/
#ifndef INET225
int my_mkdir(const char* path, int p)
{
#ifdef AMITCP
if(checkusergrouplib()) p &= ~getumask();
#else
if(checksocketlib()) p &= ~getumask();
#endif
else PyErr_Clear();
if(0==mkdir(path))
{
return chmod(path,p);
}
return -1;
}
#endif /* !INET225 */
int uname(struct utsname *u)
{
int res;
strcpy(u->sysname,"AmigaDOS");
strcpy(u->machine,"m68k");
if (!checksocketlib())
{
char *v;
PyErr_Clear();
res=0; v=getenv("HOSTNAME");
if(v) strcpy(u->nodename, v);
else strcpy(u->nodename, "localhost");
}
else res = gethostname(u->nodename, _UNAME_BUFLEN-1);
if(res>=0)
{
LONG ver_major = SysBase->LibNode.lib_Version;
LONG ver_minor = SysBase->SoftVer;
sprintf (u->release, "%d.%d", ver_major,ver_minor);
if(ver_major<36)
strcpy(u->version,"1");
else if(ver_major<39)
strcpy(u->version,"2");
else
strcpy(u->version,"3");
}
return 0;
}
#ifndef INET225
FILE *popen(const char *command, const char *type)
{
char file[50];
FILE *fh;
static int num = 1;
if((type[0]!='r') && (type[0]!='w'))
{
errno=EINVAL;
return 0;
}
sprintf(file,"PIPE:Py_%ld_%ld",num++,FindTask(0));
if(fh=fopen(file,type))
{
BPTR fh2;
LONG mode=MODE_NEWFILE; /* 'r'-peer must write */
if(type[0]=='w') mode=MODE_OLDFILE; /* peer must read */
if(fh2=Open(file,mode))
{
BPTR fh3;
if(type[0]=='r')
{
/* execute command with output to fh */
fh3=Open("*",MODE_OLDFILE); /* should use CONSOLE: */
if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Output,fh2,
SYS_Input,fh3,TAG_DONE)))
{
return fh;
}
}
else /** if(type[0]=='w') **/
{
/* execute command with input from fh */
fh3=Open("*",MODE_NEWFILE); /* should use CONSOLE: */
if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Input,fh2,
SYS_Output,fh3,TAG_DONE)))
{
return fh;
}
}
fclose(fh); Close(fh2); if(fh3) Close(fh3);
errno=EAGAIN;
return 0;
}
fclose(fh);
}
errno=ENOENT;
return 0;
}
int pclose(FILE *stream)
{
if(stream)
{
fclose(stream);
return 0;
}
errno=EINVAL;
return -1;
}
#endif /* INET225 */
/*************** ftruncate is not yet used because of bugs in the OS FileSystem :-( ***/
#if 0
int ftruncate(int fd, long newlength)
{
struct UFB *ufb;
/*
* find the ufb *
*/
if ((ufb = __chkufb(fd)) != NULL && !(ufb->ufbflg & UFB_SOCK))
{
if(-1==SetFileSize(ufb->ufbfh,newlength,OFFSET_BEGINNING))
{
set_errno(IoErr());
return -1;
}
return 0;
}
errno = EINVAL;
return -1;
}
#endif